/*实现异步缓存区
 */

#ifndef __M_BUF_H__
#define __M_BUF_H__
#include <vector>
#include <cassert>
namespace PRJLOG
{
#define DEFAULT_BUFFER_SIZE (10 * 1024 * 1024)
#define THRESHOLD_BUFFER_SIZE (80 * 1024 * 1024)
#define LINEAR_BUFFER_SIZE (10 * 1024 * 1024)
    class Buffer
    {
    public:
        Buffer() : _buffer(DEFAULT_BUFFER_SIZE), _reader_idx(0), _writer_idx(0) {}
        // 向缓冲区中写入数据
        void push(const char *data, size_t len)
        {
            // 缓冲区容量不足
            // 1.容量扩容，进行极限测试
            ensureEnoughSize(len);
            // 1.将内容写入buffer中
            std::copy(data, data + len, &_buffer[_writer_idx]);
            // 2.将可写数据位置往后移
            movewriter(len);
        }
        // 返回可读数据的起始地址
        const char *begin()
        {
            return &_buffer[_reader_idx];
        }
        // 返回可写数据的长度
        size_t writerablesize()
        {
            // 对于可扩容来说，数据是一直可写的
            // 所以这个接口为固定容量提供
            // 这里用的缓存不是循环的
            return _buffer.size() - _writer_idx;
        }
        // 返回可读数据的长度
        size_t readerablesize()
        {
            return _writer_idx - _reader_idx;
        }
        // 移动读写位置的接口
        void movereader(size_t len)
        {
            assert(len <= readerablesize());
            _reader_idx += len;
        }
        // 交换缓冲区
        void swapbuffer(Buffer &buffer)
        {
            _buffer.swap(buffer._buffer);
            std::swap(_reader_idx, buffer._reader_idx);
            std::swap(_writer_idx, buffer._writer_idx);
        }
        // 初始化缓冲区
        void reset()
        {
            _reader_idx = 0;
            _writer_idx = 0;
        }
        // 判断缓冲区是否为空
        bool empty()
        {
            return _reader_idx == _writer_idx;
        }

    private:
        void movewriter(size_t len)
        {
            assert((_writer_idx + len) <= _buffer.size());
            _writer_idx += len;
        }
        void ensureEnoughSize(size_t len)
        {
            if (len <= writerablesize())
                return; // 容量充足直接返回
            if (_buffer.size() < THRESHOLD_BUFFER_SIZE)
            {
                _buffer.resize(_buffer.size() * 2 + len);
            } // 容量未超过阈值翻倍增长
            else
            {
                _buffer.resize(_buffer.size() + LINEAR_BUFFER_SIZE + len); // 否则线性增长
            }
        }

    private:
        std::vector<char> _buffer; // 缓冲区
        size_t _reader_idx;        // 当前可读数据的指针--用下标表示
        size_t _writer_idx;        // 当前可写数据的指针
    };
}
#endif